#include <stdio.h>
#include <stdlib.h>
#include "list.h"


list_t* new_list_node(int data) {
    list_t* node = (list_t*)malloc(sizeof(list_t));
    if (!node) {
        return NULL;
    }
    node->data = data;
    node->next = NULL;

    return node;
}

list_t *list_add(list_t* list, int data) {
    if (!list) {
        return NULL;
    }

    list_t* node = new_list_node(data);
    node->next = list;   //采用头插法插入结点

    return node;
}

void list_destroy(list_t* list) {
    //空链表无需销毁
    if (!list) {
        return;
    }

    list_t* head = list; //将头结点保存到head
    while (head != NULL) {
        list = list->next;  //循环遍历链表
        free(head);  //释放结点内存
        head = NULL;
        head = list;  //head重新保存链表头结点（这里很关键！！！）
    }
}

list_t *list_delete_node(list_t* list, list_t* node) {
    if (!list) {
        return NULL;
    }
    if (!node) {
        return list;
    }

    list_t* head = list;
    list_t* prev = NULL;

    while (list != NULL && list != node) {
        prev = list;  //保存目标结点的前一个结点
        list = list->next;
    }

    //找不到目标结点
    if(list == NULL){
        return head;
    }

    //目标结点是头结点
    if (list == head) {
        head = head->next;  //目标结点的下一个结点是头结点
        free(list);  //销毁目标结点
        list = NULL;
    }
    //目标结点是尾结点，尾结点的next指针是NULL
    else if(list->next == NULL){
        prev->next = NULL;  //目标结点的前一个结点next指针置为NULL
        free(list);  //释放目标结点
        list = NULL;
    }
    //目标结点是中间结点
    else {
        prev->next = list->next;  //目标结点的前一个结点的next指针指向目标结点的下一个结点
        list->next = NULL;
        free(list);  //释放目标结点
        list = NULL;
    }

    return head;  //返回链表头结点
}

list_t *list_delete(list_t* list, int data) {
    if (!list) {
        return NULL;
    }

    list_t* head = list;
    list_t* prev = NULL;

    //遍历查找目标结点
    while (list != NULL && list->data != data) {
        prev = list;  //保存目标结点的前一个结点
        list = list->next;
    }
    //找不到目标结点
    if (!list) {
        return  head;
    }
    //目标结点是头结点
    if (list == head) {
        head = head->next;  //原头结点的下一个结点变为新的头结点
        free(list);  //释放目标结点
        list = NULL;
    }
    //目标结点是尾部结点
    else if (list->next == NULL) {
        prev->next = NULL;  //目标结点的前一个结点next指针置为NULL
        free(list);  //销毁目标结点
        list = NULL;
    }
    //目标结点是中间结点
    else {
        prev->next = list->next;  //目标结点的前一个结点的next指针指向目标结点的下一个结点
        free(list);
        list = NULL;
    }

    return head;  //返回头结点
}

list_t *list_index_of(list_t* list, int index) {
    if (!list || index < 0) {
        return NULL;
    }

    int list_index = 0;
    while (list != NULL && list_index < index) {
        list_index++;
        list = list->next;
    }

    return list;
}

void list_print(list_t* list) {
    if (list == NULL) {
        return;
    }

    while (list != NULL) {
        printf("%d, ", list->data);
        list = list->next;
    }
    printf("\n");
}